﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace DisplayInformation
{
    public partial class Form1 : Form
    {
        private SerialPort com = new SerialPort();
        private bool receiving = true;
        private int received_count = 0;
        private List<byte> buffer = new List<byte>(4096);//创建串口缓冲区.链表型 
        byte[] MyData = new byte[4];//存放读回来的值
        UInt32 adr = 0x01;//默认地址
        UInt32 adrHistory = 0x01;
        bool adr_Flag = false;
        int Funflag=-1;
        public Form1()
        {
            InitializeComponent();
            //线程间操作无效: 从不是创建控件的线程访问它问题的解决方案，加入下面这句
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;


            string[] ports = SerialPort.GetPortNames();
            Array.Sort(ports);
            ComDisplay.Items.AddRange(ports);
            ComDisplay.SelectedIndex = ComDisplay.Items.Count > 0 ? 0 : -1;
            com.DataReceived += com_DataReceived;
            timer1.Start();

        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            handle();
        }
        void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (!com.IsOpen) return;
            //如果正在关闭，忽略操作，直接返回，尽快的完成串口监听线程的一次循环  
            receiving = true;//正在接收处理数据
            int n = com.BytesToRead;//先记录缓存
            byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
            received_count += n;//增加接收计数
            com.Read(buf, 0, n);//读取缓冲数据
            buffer.AddRange(buf);

            textBox1.Text = "接收数据:\r\n" + string.Join(",", buffer);//显示当前收到的数据
            //textBox3.Text = Funflag.ToString() + "接收ing";
        }

        void handle()
        {
            while (buffer.Count >= 7)//Min 7 byte
            {
                //检测到功能码
                if (0x03 == buffer[1])
                {
                    //数据位足够
                    if (buffer[2] + 5 <= buffer.Count)
                    {
                        byte[] Data = new byte[buffer[2] + 5];
                        buffer.CopyTo(0, Data, 0, buffer[2] + 5);
                        UInt16 CRC = CRC_CHECK(Data, Data.Length - 2);
                        if ((CRC & 0xff) == Data[Data.Length - 2]
                            && ((CRC & 0xff00) >> 8) == Data[Data.Length - 1])
                        {
                            if (1 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox4.Text = float.Parse(BitConverter.ToSingle(BitConverter.GetBytes(x), 0).ToString()).ToString("00.0");
                            }


                            if (13 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox18.Text = float.Parse(BitConverter.ToSingle(BitConverter.GetBytes(x), 0).ToString()).ToString("0.000");
                            }
                            if (14 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox17.Text = float.Parse(BitConverter.ToSingle(BitConverter.GetBytes(x), 0).ToString()).ToString("0.000");
                            }
                            if (2 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox5.Text = x.ToString();
                            }

                            if (11 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox12.Text = x.ToString();
                            }


                            if (3 == Funflag)
                            {
                                adr_Flag = true;//读到地址了
                                buffer.CopyTo(3, MyData, 0, 2);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 8) + MyData[1]);
                                adrHistory = adr = (UInt32)(x & 0x0000ffff);
                                textBox6.Text = x.ToString();
                            }

                            if (12 == Funflag)
                            {
                                adr_Flag = true;//读到地址了
                                buffer.CopyTo(3, MyData, 0, 2);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 8) + MyData[1]);
                                adrHistory = adr = (UInt32)(x & 0x0000ffff);
                                textBox11.Text = x.ToString();
                            }

                            if (15 == Funflag)
                            {
                                adr_Flag = true;//读到地址了
                                buffer.CopyTo(3, MyData, 0, 2);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 8) + MyData[1]);
                                adrHistory = adr = (UInt32)(x & 0x0000ffff);
                                textBox16.Text = x.ToString();
                            }
                            
                            if (8 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox13.Text = float.Parse(BitConverter.ToSingle(BitConverter.GetBytes(x), 0).ToString()).ToString("00.0");
                            }

                            if (9 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox20.Text = float.Parse(BitConverter.ToSingle(BitConverter.GetBytes(x), 0).ToString()).ToString("00.000");
                            }

                            if (10 == Funflag)
                            {
                                buffer.CopyTo(3, MyData, 0, 4);
                                UInt32 x = (UInt32)((UInt32)(MyData[0] << 24) + (UInt32)(MyData[1] << 16) + (UInt32)(MyData[2] << 8) + MyData[3]);
                                textBox19.Text = float.Parse(BitConverter.ToSingle(BitConverter.GetBytes(x), 0).ToString()).ToString("00.000");
                            }

                            /*
                            
                            textBox3.Text = string.Join("----", MyData);//显示校验成功的数据
                            */
                            //校验成功
                            textBox1.Text += "\r\n---CRC校验成功---";//显示校验成功的数据
                            buffer.RemoveRange(0, Data.Length);
                        }
                        else
                        {
                            //校验失败
                            buffer.RemoveAt(0);
                        }
                    }
                }
                else
                {
                    if (0x10 == buffer[1])
                    {

                        if (buffer.Count >= 8)
                        {
                            byte[] Data = new byte[8];
                            buffer.CopyTo(0, Data, 0, 8);

                            UInt16 CRC = CRC_CHECK(Data, Data.Length - 2);
                            if ((CRC & 0xff) == Data[Data.Length - 2]
                            && ((CRC & 0xff00) >> 8) == Data[Data.Length - 1])
                            {

                                //校验成功   
                                if (4 == Funflag || 6 == Funflag)
                                {
                                    textBox1.Text += "\r\n---写入成功---\r\n";//显示校验成功的数据
                                }



                                if (5 == Funflag || 7 == Funflag||16 == Funflag)
                                {
                                    if (adrHistory == (UInt32)(Data[0] & 0x000000ff))
                                    {
                                        textBox1.Text += "\r\n---写入地址成功---\r\n";//显示校验成功的数据
                                        //MessageBox.Show("---写入地址成功---");
                                        adr = adrHistory;
                                    }
                                    else
                                    {
                                         textBox1.Text = "---写入地址失败,请重新写入---\r\n";//显示校验成功的数据
                                        //adr = adrHistory;
                                        //MessageBox.Show("---写入地址失败,请重新操作---");
                                    }
                                }
                                buffer.RemoveRange(0, Data.Length);

                            }
                            else
                            {
                                buffer.RemoveAt(0);
                                continue;
                            }
                        }

                    }
                    else
                    {
                        buffer.RemoveAt(0);
                    }
                }
            }

        }




        byte LRC(byte[] auchMsg, UInt16 usDataLen)
        {

            byte uchLRC = 0;
            while ((usDataLen--) != 0)
                uchLRC += auchMsg[usDataLen];
            return ((byte)(((uchLRC))));

        }

        /***************CRC校验****************/
        UInt16 CRC_CHECK(byte[] Buf, int CRC_CNT)
        {
            UInt16 CRC_Temp;
            byte i, j;
            CRC_Temp = 0xffff;

            for (i = 0; i < CRC_CNT; i++)
            {
                CRC_Temp ^= Buf[i];
                for (j = 0; j < 8; j++)
                {
                    if ((CRC_Temp & 0x01) != 0)
                        CRC_Temp = (UInt16)((CRC_Temp >> 1) ^ 0xa001);
                    else
                        CRC_Temp = (UInt16)(CRC_Temp >> 1);
                }
            }
            return (CRC_Temp);
        }

        void OutPut_Data(string str)
        {

            //string str = textBox2.Text;
            string[] s = str.Split(' ');
            UInt16 LEN = (UInt16)s.Length;
            byte[] OutData = new byte[LEN + 2];
            StringToByte(s, OutData, LEN);
            UInt16 CRC16 = 0;
            byte[] Lrc = new byte[1];
            /*******LRC校验**********
            Lrc[0] = LRC(OutData, (UInt16)(LEN - 1));
            com.Write(Lrc, 0, 1);
            **********************/


            CRC16 = CRC_CHECK(OutData, LEN);
            OutData[LEN] = (byte)(CRC16 % 256);
            OutData[LEN + 1] = (byte)(CRC16 / 256);
            
            //提取功能码
            //funNum = OutData[1];
            //textBox1.Text = string.Join(" ", OutData);
            try
            {
                com.Write(OutData, 0, OutData.Length);
                textBox3.Text = "发送数据:\r\n" + string.Join(" ", OutData);
            }
            catch (Exception e)
            {
                MessageBox.Show("请先开启串口!");
            }
        }



        private void button1_Click(object sender, EventArgs e)
        {
            SerialOpen();
        }







        public void SerialOpen()
        {

            if (com.IsOpen)//串口是开着的,进来关
            {

                //while (receiving) Application.DoEvents();
                //如果正在接收数据则继续去处理数据,等到第二次进入则跳出数据接收
                //打开时点击，则关闭串口
                com.Close();

                foreach (Control control in this.Controls)
                {
                    //if (control is NumericUpDown)
                    //   ((NumericUpDown)control).Enabled = true;
                    control.Enabled = true;
                }

                //设置按钮的状态
                button1.Text = com.IsOpen ? "关闭串口" : "打开串口";
            }
            else
            {
                //关闭时点击，则设置好端口，波特率后打开
                com.PortName = ComDisplay.Text;
                com.BaudRate = 9600;
                com.Parity = Parity.None;//无校验
                com.StopBits = StopBits.One;
                com.DataBits = 8;

                try
                {
                    com.Open();
                    //设置按钮的状态
                    button1.Text = com.IsOpen ? "关闭串口" : "打开串口";
                    ComDisplay.Enabled = false;

                }
                catch (Exception ex)
                {
                    //捕获到异常信息，创建一个新的com对象，之前的不能用了。
                    com = new SerialPort();
                    //显示异常信息给客户。
                    MessageBox.Show(ex.Message);
                }

            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Funflag = 1;
            string st = Convert.ToString(adr, 16) + " 03 00 10 00 02";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:"+st;
        }
        private void StringToByte(string[] s, byte[] data, Int32 LEN)
        {
            for (Int32 i = 0; i < LEN; i++)
            {
                data[i] = Convert.ToByte(s[i], 16);
            }
        }
        
        private void button3_Click(object sender, EventArgs e)
        {
            
            Funflag = 2;
            string st = Convert.ToString(adr, 16) + " 03 00 12 00 02";
            OutPut_Data(st);
            ////textBox3.Text = "发送数据:" + st;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Funflag = 3;
            adr_Flag = false;
            string st = "FF 03 00 03 00 01";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;

            //System.Threading.Thread.Sleep(5); //sleep 0.5s
            /*LostTime(10);
            while (!adr_Flag)//读不到地址就连续读
            {
                
                adr++;
                if(adr==255)
                {
                   MessageBox.Show("读不到设备,请检测设备型号!");
                   adr = 0;
                   break;
                }
                OutPut_Data(Convert.ToString(adr, 16) + " 03 00 03 00 01");
                textBox3.Text = Funflag.ToString() + "地址"+Convert.ToString(adr, 16)+"发送成功";
                LostTime(10);
            }*/
        }

        private void button5_Click(object sender, EventArgs e)
        {
            
            Funflag = 4;
            //string[] test = new string[4]; 
            UInt32 a = 0;
            string s = textBox7.Text;
            a = UInt32.Parse(s);



            s = Convert.ToString(((a & 0xff000000) >> 24),16)+" "+
                Convert.ToString(((a & 0x00ff0000) >> 16),16) + " " +
                Convert.ToString(((a & 0x0000ff00) >> 8),16) + " " +
                Convert.ToString((a & 0x000000ff),16);

            //OutPut_Data(Convert.ToString(adr, 16) + " 10 00 12 00 02 02 " + s);
           // textBox3.Text = Funflag.ToString() + "发送成功：" + s ;
            string st = Convert.ToString(adr, 16) + " 10 00 12 00 02 02 " + s;
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            //

            Funflag = 5;//修改地址
            //string[] test = new string[4]; 
            UInt32 a = 0;
            string s = textBox8.Text;
            a = UInt32.Parse(s);
            adrHistory = a;//把地址保存起来,用于往后的对比
            s = Convert.ToString(((a & 0x0000ff00) >> 8), 16) + " " +
            Convert.ToString((a & 0x000000ff),16);

            //OutPut_Data(Convert.ToString(adr, 16) + " 10 00 03 00 01 01 " + s);
           // textBox3.Text = Funflag.ToString() + "发送成功：" + s ;


            string st = Convert.ToString(adr, 16) + " 10 00 03 00 01 01 " + s;
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;


            adrHistory = adr = a;
        }




        public void LostTime(UInt16 ms)
        {
            long beginTime = DateTime.Now.Ticks;
            long endTime=0;
            while (true)
            {
                endTime = DateTime.Now.Ticks;
                if ((endTime - beginTime) / 10000.0 > ms) break;
            }
            //MessageBox.Show((endTime - beginTime).ToString());
            return;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            Funflag = 6;
            UInt32 a = 0;
            string s = textBox10.Text;
            a = UInt32.Parse(s);



            s = Convert.ToString(((a & 0xff000000) >> 24), 16) + " " +
                Convert.ToString(((a & 0x00ff0000) >> 16), 16) + " " +
                Convert.ToString(((a & 0x0000ff00) >> 8), 16) + " " +
                Convert.ToString((a & 0x000000ff), 16);

            //OutPut_Data(Convert.ToString(adr, 16) + " 10 00 36 00 02 02 " + s);
            //textBox3.Text = Funflag.ToString() + "发送成功：" + s;


            string st = Convert.ToString(adr, 16) + " 10 00 36 00 02 02 " + s;
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button7_Click(object sender, EventArgs e)
        {
            Funflag = 7;//修改地址
            UInt32 a = 0;
            string s = textBox9.Text;
            a = UInt32.Parse(s);
            adrHistory = a;//把地址保存起来,用于往后的对比
            s = Convert.ToString(((a & 0x0000ff00) >> 8), 16) + " " +
            Convert.ToString((a & 0x000000ff), 16);

            //OutPut_Data(Convert.ToString(adr, 16) + " 10 00 23 00 01 01 " + s);
            //textBox3.Text = Funflag.ToString() + "发送成功：" + s;


            string st = Convert.ToString(adr, 16) + " 10 00 23 00 01 01 " + s;
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
            adrHistory = adr = a;
        }

        private void button11_Click(object sender, EventArgs e)
        {
            Funflag = 8;
            //OutPut_Data(Convert.ToString(adr, 16) + " 03 00 30 00 02");
            //textBox3.Text = Funflag.ToString() + "发送成功";

            string st = Convert.ToString(adr, 16) + " 03 00 30 00 02";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button18_Click(object sender, EventArgs e)
        {
            Funflag = 9;
            //OutPut_Data(Convert.ToString(adr, 16) + " 03 00 32 00 02");
            //textBox3.Text = Funflag.ToString() + "发送成功";

            string st = Convert.ToString(adr, 16) + " 03 00 32 00 02";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button17_Click(object sender, EventArgs e)
        {
            Funflag = 10;
           // OutPut_Data(Convert.ToString(adr, 16) + " 03 00 34 00 02");
            //textBox3.Text = Funflag.ToString() + "发送成功";

            string st = Convert.ToString(adr, 16) + " 03 00 34 00 02";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button10_Click(object sender, EventArgs e)
        {
            Funflag = 11;
            //OutPut_Data(Convert.ToString(adr, 16) + " 03 00 36 00 02");
            //textBox3.Text = Funflag.ToString() + "发送成功";

            string st = Convert.ToString(adr, 16) + " 03 00 36 00 02";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button9_Click(object sender, EventArgs e)
        {
            Funflag = 12;
            adr_Flag = false;
            //OutPut_Data("FF 03 00 23 00 01");
            //textBox3.Text = Funflag.ToString() + "地址" + Convert.ToString(adr, 16) + "发送成功";

            string st = "FF 03 00 23 00 01";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;

        }

        private void button16_Click(object sender, EventArgs e)
        {
            Funflag = 13;
            //OutPut_Data(Convert.ToString(adr, 16) + " 03 00 60 00 02");
            //textBox3.Text = Funflag.ToString() + "发送成功";

            string st = Convert.ToString(adr, 16) + " 03 00 60 00 02";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button15_Click(object sender, EventArgs e)
        {
            Funflag = 14;
            //OutPut_Data(Convert.ToString(adr, 16) + " 03 00 62 00 02");
            //textBox3.Text = Funflag.ToString() + "发送成功";

            string st = Convert.ToString(adr, 16) + " 03 00 62 00 02";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button14_Click(object sender, EventArgs e)
        {
            Funflag = 15;
            adr_Flag = false;
            //OutPut_Data("FF 03 00 53 00 01");
            //textBox3.Text = Funflag.ToString() + "地址" + Convert.ToString(adr, 16) + "发送成功";

            string st = "FF 03 00 53 00 01";
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;
        }

        private void button12_Click(object sender, EventArgs e)
        {
            Funflag = 16;//修改地址
            UInt32 a = 0;
            string s = textBox14.Text;
            a = UInt32.Parse(s);
            adrHistory = a;//把地址保存起来,用于往后的对比
            s = Convert.ToString(((a & 0x0000ff00) >> 8), 16) + " " +
            Convert.ToString((a & 0x000000ff), 16);

            //OutPut_Data(Convert.ToString(adr, 16) + " 10 00 53 00 01 01 " + s);
            //textBox3.Text = Funflag.ToString() + "发送成功：" + s;

            string st = Convert.ToString(adr, 16) + " 10 00 53 00 01 01 " + s;
            OutPut_Data(st);
            //textBox3.Text = "发送数据:" + st;

            adrHistory = adr = a;
        }









    }

}
